<?php

namespace app\bll;

use app\lib\installer\General as LibInstallerGeneral;
use Exception;
use hulang\tool\FileHelper;
use PhpZip\ZipFile;
use support\Db;
use clagiordano\weblibs\configmanager\ConfigManager;

/**
 * 框架本身相关业务
 */
class Frame
{

    /**
     * 在线升级
     */
    public function onlineUpgrade()
    {

        $frameinfo = $this->getFrameInfo();
        if (
            !isset($frameinfo['upgrade'])
            || $frameinfo['upgrade'] == ''
            || !isset($frameinfo['nextversion'])
            ||  $frameinfo['nextversion'] == ''
        ) {
            throw new Exception('没有找到升级包');
        }

        try {
            //下载文件
            $zipfilepath = $this->downRemoteFile($frameinfo);
            //释放文件
            $extractpath = $this->extractZip($zipfilepath);

            //执行SQL
            $sqlfile = $extractpath . '/database.sql';
            $this->ExecuteSql($sqlfile);



            //写入配置文件
            $config = new ConfigManager(config_path() . "/frame.php");
            $config->setValue('version', $frameinfo['nextversion']);
            $config->setValue('nextversion', '');
            $config->saveConfigFile();

            //移动文件
            FileHelper::copyDir($extractpath . '/source', base_path());
        } catch (Exception $ex) {
            throw $ex;
        }
    }

    /**
     * 当前版本号
     *
     * @return string
     */
    public function nowVersion(): string
    {
        return config('frame')['version'];
    }

    /**
     * 下一个版本号
     *
     * @return void
     */
    public function nextVersion()
    {

        $this->checkUpgrade();
    }

    /**
     * 获取框架版本/升级地址等信息
     *
     * @return array
     */
    public function getFrameInfo()
    {
        return config('frame');
    }

    /**
     * 检查更新
     *
     * @return void
     */
    public function checkUpgrade()
    {
        $upgrade = config('frame')['upgrade'];
        $libInstallerGeneral = new LibInstallerGeneral();
        $nextVersion = $libInstallerGeneral->getNextUpgradeVersion($upgrade, $this->nowVersion());
        if ($nextVersion && $nextVersion['nextVersion'] != '') {
            if (config('frame')['nextversion'] != $nextVersion['nextVersion']) {
                $config = new ConfigManager(config_path() . "/frame.php");
                $config->setValue('nextversion', $nextVersion['nextVersion']);
                $config->saveConfigFile();
            }
        }
    }


    /**
     * 执行SQL 文件
     */
    private function ExecuteSql(string $sqlfile)
    {
        if (file_exists($sqlfile)) {
            try {

                $sql = file_get_contents($sqlfile);
                if (trim($sql) != '') {
                    $sql = str_replace('{{prefix}}', getDatabasePrefix(), $sql);
                    Db::unprepared($sql);
                }
            } catch (Exception $ex) {
                throw $ex;
            }
        }
    }


    /**
     * 下载远程文件
     * @param string $url 远程文件地址
     */
    private function downRemoteFile(array  $frameinfo)
    {
        $libInstallerGeneral = new LibInstallerGeneral();
        $nextVersion = $libInstallerGeneral->getNextUpgradeVersion($frameinfo['upgrade'], $frameinfo['version']);
        if (!$nextVersion) {
            throw new Exception('没有找到升级包');
        }

        //下载升级包
        return  $libInstallerGeneral->downloadUpgradeZip($nextVersion['upgradeUrl'], 'upgrade');
    }

    /**
     * 释放文件
     *
     * @param string $zipfile
     * @param string $tofolder
     * @return void
     */
    public function extractZip(string $zipfile)
    {
        $zipFile = new ZipFile();
        $zipFile->openFile($zipfile);

        $extractpath = runtime_path() . '/storage/upgrade/frame/' . time();

        if (!file_exists($extractpath)) {
            mkdir($extractpath, 0777, true);
        }

        $zipFile->extractTo($extractpath);
        return $extractpath;
    }
}
